﻿using System;
using LunoCode.Render;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace LunoCode
{
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class LunoGame : Game
	{
		GraphicsDeviceManager graphics;
		SpriteBatch spriteBatch;

		public static readonly int Height = 1024;
		public static readonly int Width = 768;

		Terrain terrain;
		Camera camera;
		SkyDome sky;
		DuelPlace place;

		public LunoGame()
		{
			graphics = new GraphicsDeviceManager(this);
			#if PERFHUD_ENABLED
			graphics.PreparingDeviceSettings += graphics_PreparingDeviceSettings;
			#endif
			Content.RootDirectory = "Content";
		}

		void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
		{
			foreach (GraphicsAdapter curAdapter in GraphicsAdapter.Adapters)
			{
				if (curAdapter.Description.Contains("NVIDIA PerfHUD"))
				{
					e.GraphicsDeviceInformation.Adapter = curAdapter;
					e.GraphicsDeviceInformation.DeviceType = DeviceType.Reference;
					break;
				}
			}
		}

		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;

			camera = new Camera(new Vector3(30518.31f, 22893.47f, -47963.19f), new Vector3(-0.01832225f, -0.6800076f, 0.7329761f));

			graphics.PreferredBackBufferWidth = Height;
			graphics.PreferredBackBufferHeight = Width;
			graphics.ApplyChanges();
			Mouse.SetPosition(Width / 2, Height / 2);

			//graphics.ToggleFullScreen();
			base.Initialize();
		}

		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent()
		{
			// Create a new SpriteBatch, which can be used to draw textures.
			spriteBatch = new SpriteBatch(GraphicsDevice);

			LoadHelper.Load(Content);

			terrain = new Terrain();
			terrain.Init(GraphicsDevice, LoadHelper.Textures[TextureEnum.HeightMap]);

			sky = new SkyDome();
			sky.LoadSkyDome(GraphicsDevice, LoadHelper.Effects[EffectEnum.Phong], LoadHelper.Models[ModelEnum.Skydome]);

			place = new DuelPlace(GraphicsDevice, new Vector3(30712.88f, 9029.713f, -34139.74f), new Vector3(0, MathHelper.PiOver2, 0));
		}

		/// <summary>
		/// UnloadContent will be called once per game and is the place to unload
		/// all content.
		/// </summary>
		protected override void UnloadContent()
		{
			// TODO: Unload any non ContentManager content here
		}

		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update(GameTime gameTime)
		{
			// Allows the game to exit
			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
				this.Exit();

			base.Update(gameTime);
		}

		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw(GameTime gameTime)
		{
			if (IsActive)
			{
				GraphicsDevice.Clear(Color.Black);

				camera.Input();
				sky.Draw(camera.View, camera.Proj);

				terrain.Draw(GraphicsDevice, LoadHelper.Textures[TextureEnum.Moon],
									LoadHelper.Effects[EffectEnum.Phong], camera.View, camera.Proj);
                place.Draw(GraphicsDevice, camera.View, camera.Proj);

				if (Keyboard.GetState().IsKeyDown(Keys.Escape))
					this.Exit();
				base.Draw(gameTime);
			}
		}
	}
}
